package maintain

import (
	"encoding/json"
	"iot-base/common/dbconn"
	"iot-base/common/notify"
	"iot-base/common/webapi"
	"time"

	"github.com/gin-gonic/gin"

	"gorm.io/datatypes"
)

//SystemInfo 数据库系统统计分析信息
type SystemInfo struct {
	CalcTime time.Time      `gorm:"primaryKey" json:"calc_time"`
	Result   datatypes.JSON `json:"result"`
}

var lasttime int64

func timerRun() {
	getSystemStatics()
	ticker := time.NewTicker(60 * 15 * time.Second)
	for range ticker.C {
		getSystemStatics()
	}
}

func prepareStatics() {
	time.Sleep(time.Minute)
	getSystemStatics()
}

func init() {
	dbconn.DBConnection.AutoMigrate(&SystemInfo{})
	//定时启动，15分钟统计一次
	go timerRun()
	notify.SubOnline(func(pMsg *notify.OnlineNotify) {
		go prepareStatics()
	})
	notify.SubOffline(func(pMsg *notify.OnlineNotify) {
		go prepareStatics()
	})

}

func getSystemStatics() error {
	now := time.Now().Unix()
	if now-lasttime < 30 {
		return nil
	}
	lasttime = now
	result := make(map[string]([]map[string]interface{}))

	sqlMap := make(map[string]string)
	sqlMap["by_model"] = `select t_models.s_name,model_id,things.is_station,count(*) 
	from things,t_models 
	where t_models.uid = things.model_id group by (model_id , t_models.s_name,things.is_station)`

	sqlMap["by_state"] = `select count(*),thing_states.state from things,thing_states 
	where things.uid = thing_states.thing_id and things.is_station = false and things.status_used = 1 group by(thing_states.state)`

	sqlMap["by_alarm"] = `select count(*) from alarm_states where alarm_states.is_alarm = true`
	sqlMap["by_no_alarm"] = `select count(*) from things where things.status_used =1 and things.uid
	not in (select t_id from alarm_states where alarm_states.is_alarm = true)`
	sqlMap["by_catalog"] = `select catalogs.s_name,count(*) 
	from things,t_models,catalogs
	where t_models.uid = things.model_id and catalogs.uid=t_models.catalog_id 
	group by (t_models.catalog_id,catalogs.s_name)`
	sqlMap["by_alarm_type"] = `select count(alarm_id),alarm_id,alarm_name
	from alarm_states 
	where alarm_states.is_alarm=true
	group by alarm_states.alarm_id,alarm_states.alarm_name`

	sqlMap["by_alarm_level"] = `select count(level),level
	from alarm_states 
	where alarm_states.is_alarm=true
	group by alarm_states.level`

	sqlMap["ipc_online"] = `select count(*),thing_states.state from things,thing_states 
	where things.uid = thing_states.thing_id  and 
	things.status_used = 1 and (things.model_id='m_SlTrLORmaPXHeS3Xrocpz' or things.model_id='m_ipc') group by(thing_states.state)`

	sqlMap["box_online"] = `select count(*),thing_states.state from things,thing_states 
	where things.uid = thing_states.thing_id  and 
	things.status_used = 1 and things.model_id='m_smartBoxForPolice' group by(thing_states.state)`

	for k, sql := range sqlMap {
		var statics [](map[string]interface{})
		dbconn.DBConnection.Raw(sql).Scan(&statics)
		result[k] = statics
	}
	cr, err := json.Marshal(&result)
	if err == nil {
		info := SystemInfo{
			CalcTime: time.Now(),
			Result:   cr,
		}
		return dbconn.DBConnection.Save(info).Error
	}
	return err

	//fmt.Println("---------", statics)
}

func initStaticAPI(router *gin.RouterGroup) {
	router.GET("/system", func(c *gin.Context) {

		endt := time.Now()
		begint := endt
		aday, _ := time.ParseDuration("-24h")
		begint = begint.Add(aday)
		begin := c.Query("begintime")
		end := c.Query("endtime")
		if begin != "" {
			begint, _ = time.Parse("2006-01-02 15:04:05", begin)
		}
		if end != "" {
			endt, _ = time.Parse("2006-01-02 15:04:05", end)
		}
		var result []SystemInfo
		err := dbconn.DBConnection.Where("calc_time >=? and calc_time <= ?", begint, endt).Order("calc_time").Find(&result).Error
		if err != nil {
			webapi.SendError(err.Error(), webapi.DBError, c)
		} else {
			webapi.SendResult(result, nil, c)
		}

	})
	router.POST("/system", func(c *gin.Context) {
		err := getSystemStatics()
		if err == nil {
			webapi.SendOK(c)
		} else {
			webapi.SendError(err.Error(), webapi.DBError, c)
		}

	})

}
